來到鐵人挑戰的第六天,今天要講的是 Laravel 提供的 Migration (遷移)功能,在以往只寫純 PHP 時,我們都是需要自行透過 SQL 語法或是 phpmyadmin 等工具建立資料表,但是 Laravel 提供的 Migration 功能,可以讓我們透過程式自行建構資料表,除此之外,它也提供了 rollback
、reset
、refresh
、fresh
等有點可怕的快速回滾、重設、重建資料表的指令。
首先,我們透過昨天所提到的 artisan
語法建好 Migration 所需的程式檔案。
php artisan make:migration create_animals_table --create=animals
這個與指令會在 database/migrations
下建立一個檔案 2020_09_21_XXXXXX_create_animals_table.php
,而這個檔案能夠幫助你建立 animals
這張資料表,--create=animals
則會幫助你在這個檔案內先將 Schema 指向 animals
資料表,我會建議這個檔案的命名規則依照此規範,若需要增加/修改某個元素也是如下所示。
php artisan make:migration add_species_column_to_table --table=animals
# 或是
php artisan make:migration alter_sex_column_of_table --table=animals
使用 --table
將要修改的資料表指向 animals
,我自己在命名這個檔案會將對這個資料表的操作方式放在開頭,中段說明要如何執行,table
作為結尾,以此語意化的方式進行檔案命名,以便後續若需要重建資料表時了解自己之前幹了甚麼好事。
進入到 Migration 檔案內,我們可以先大致看一下程式的結構,並以建立 animals
作為範例,至於其他資料表欄位如何建立,可參照官方文件。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateAnimalsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('animals', function (Blueprint $table) {
$table->increments('id');
$table->string('sex');
$table->integer('number');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('animals');
}
}
若是我們以上面的程式碼為例,執行修改資料表的指令。修改/刪除欄位參考
php artisan make:migration add_species_column_to_table --table=animals
程式碼如下
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddSpeciesColumnToTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('animals', function (Blueprint $table) {
$table->string('species')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('animals', function (Blueprint $table) {
$table->dropColumn('species');
});
}
}
程式碼 function 裡面 up
代表的是執行 Migrate 時的動作。
程式寫好後便可執行以下指令建立資料表囉!
php artisan migrate
而在 down
內則代表資料表的 rollback (回滾)時會執行的程式,執行 rollback 指令如下。
php artisan migrate:rollback
執行這個指令,資料表會批次的 rollback 至你上一次執行的 Migration 位置,Laravel 本身有將這個執行的順序紀錄在一張 migrations
的資料表內。
這邊建議若是
up
裡面執行甚麼程式,down
內就的操作就是將up
反著執行,這樣才能正常執行資料表的建立以及回復,我有看過開發者不寫down
函式,透過 phpmyadmin 直接刪除所有資料表,再重新執行php artisan migrate
,拜託大家不要這樣幹,因為這個指令並不會幫你保留已儲存的資料,你永遠不知道自己會不會操作錯誤,導致發生無法挽回的事情。
這個指令是會一次回復(執行 down
)「所有」資料表,使用請小心。
php artisan migrate:reset
這個指令則是一次執行 reset
+ migrate
,因此如果沒有好好寫 down
函式的人就會噴錯囉!
php artisan migrate:refresh
這個指令是「刪除」所有資料表後執行 migrate
,恩,史上最危險。
php artisan migrate:fresh
在某些情境中,當你建立的資料表有誤或是結構需要修改,通常會有兩種做法。
down
內所編寫的程式執行,一般來說就是回復到上一次執行 migrate 前的步驟。php artisan migrate:rollback
然後重新修改 Migration 檔案內 up
所執行的動作,並再次執行 Migration。
php artisan migrate
不建議使用這個方法的原因一樣同上,因為 Laravel 執行 Migration 以及 rollback 的方式都是從這次新建的「所有」檔案開始執行,因此你可能會一次執行多個 PHP 檔案,這樣會有已新增的資料被覆蓋的風險存在。
php artisan make:migration alter_sex_column_of_table --table=animals
檔案內程式碼
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AlterSexColumnOfTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('animals', function (Blueprint $table) {
$table->string('sex')->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('animals', function (Blueprint $table) {
$table->string('sex')->nullable(false)->change();
});
}
}
執行以下指令
php artisan migrate
這個方法只需要執行一次 Migration 指令,不會受之前所建的檔案影響,風險相對小很多,只是若你在事前沒有好好規劃資料庫的欄位以及結構,你的 Migration 檔案會非常多,上到一個乾淨的環境執行會一次跑所有的檔案,看起來會很壯觀XD,所以最正確的做法還是先進行開發前資料庫欄位、結構的規劃,再來撰寫 Migration 檔案唷!
想不到今天篇幅這麼長,那這樣 ERD 的規劃就留給明天吧 ╮(╯∀╰)╭ (懶)